/// 网络异常模型
/// 
/// 统一的网络错误处理模型，提供标准化的错误信息
/// 抽象了底层网络库的具体实现
/// 
/// 企业级错误码体系：
/// - 10xxx: 认证授权错误
/// - 11xxx: 业务错误
/// - 50xxx: 系统错误
class NetworkExceptionModel implements Exception {
  /// 错误代码
  final String code;
  
  /// 错误消息
  final String message;
  
  /// HTTP状态码（如果有）
  final int? statusCode;
  
  /// 业务错误码（如果有）
  final int? businessCode;
  
  /// 错误类型
  final NetworkErrorType type;
  
  /// 原始异常（用于调试）
  final dynamic originalException;
  
  /// 请求路径（用于日志）
  final String? requestPath;
  
  /// 请求方法（用于日志）
  final String? requestMethod;

  const NetworkExceptionModel({
    required this.code,
    required this.message,
    required this.type,
    this.statusCode,
    this.businessCode,
    this.originalException,
    this.requestPath,
    this.requestMethod,
  });

  /// 创建连接超时异常
  factory NetworkExceptionModel.connectionTimeout({
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'CONNECTION_TIMEOUT',
      message: '连接超时，请检查网络连接',
      type: NetworkErrorType.timeout,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建请求超时异常
  factory NetworkExceptionModel.requestTimeout({
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'REQUEST_TIMEOUT',
      message: '请求超时，请重试',
      type: NetworkErrorType.timeout,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建网络连接异常
  factory NetworkExceptionModel.connectionError({
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'CONNECTION_ERROR',
      message: '网络连接失败，请检查网络设置',
      type: NetworkErrorType.network,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建认证异常
  factory NetworkExceptionModel.unauthorized({
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'UNAUTHORIZED',
      message: '未授权，请重新登录',
      type: NetworkErrorType.authorization,
      statusCode: 401,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建Token过期异常（业务码10001）
  factory NetworkExceptionModel.tokenExpired({
    String? message,
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'TOKEN_EXPIRED',
      message: message ?? 'Token已过期，请重新登录',
      type: NetworkErrorType.authorization,
      statusCode: 401,
      businessCode: 10001,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建Token无效异常（业务码10002）
  factory NetworkExceptionModel.tokenInvalid({
    String? message,
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'TOKEN_INVALID',
      message: message ?? 'Token无效，请重新登录',
      type: NetworkErrorType.authorization,
      statusCode: 401,
      businessCode: 10002,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建Token签名错误异常（业务码10003）
  factory NetworkExceptionModel.tokenSignatureError({
    String? message,
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'TOKEN_SIGNATURE_ERROR',
      message: message ?? 'Token签名错误，请重新登录',
      type: NetworkErrorType.authorization,
      statusCode: 401,
      businessCode: 10003,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建权限不足异常
  factory NetworkExceptionModel.forbidden({
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'FORBIDDEN',
      message: '禁止访问，权限不足',
      type: NetworkErrorType.authorization,
      statusCode: 403,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建资源不存在异常
  factory NetworkExceptionModel.notFound({
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'NOT_FOUND',
      message: '请求的资源不存在',
      type: NetworkErrorType.client,
      statusCode: 404,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建服务器错误异常
  factory NetworkExceptionModel.serverError({
    int? statusCode,
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'SERVER_ERROR',
      message: '服务器内部错误',
      type: NetworkErrorType.server,
      statusCode: statusCode ?? 500,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建请求取消异常
  factory NetworkExceptionModel.cancelled({
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'CANCELLED',
      message: '请求已取消',
      type: NetworkErrorType.cancelled,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建数据解析异常
  factory NetworkExceptionModel.parseError({
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'PARSE_ERROR',
      message: '数据解析失败',
      type: NetworkErrorType.parse,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建通用HTTP异常
  factory NetworkExceptionModel.httpError({
    required int statusCode,
    String? message,
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    final errorMessage = message ?? _getDefaultHttpErrorMessage(statusCode);
    final errorType = _getErrorTypeFromStatusCode(statusCode);
    
    return NetworkExceptionModel(
      code: 'HTTP_$statusCode',
      message: errorMessage,
      type: errorType,
      statusCode: statusCode,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 创建未知异常
  factory NetworkExceptionModel.unknown({
    String? message,
    String? requestPath,
    String? requestMethod,
    dynamic originalException,
  }) {
    return NetworkExceptionModel(
      code: 'UNKNOWN',
      message: message ?? '未知网络错误',
      type: NetworkErrorType.unknown,
      requestPath: requestPath,
      requestMethod: requestMethod,
      originalException: originalException,
    );
  }

  /// 根据状态码获取默认错误信息
  static String _getDefaultHttpErrorMessage(int statusCode) {
    switch (statusCode) {
      case 400:
        return '请求参数错误';
      case 401:
        return '未授权，请重新登录';
      case 403:
        return '禁止访问，权限不足';
      case 404:
        return '请求的资源不存在';
      case 405:
        return '请求方法不被允许';
      case 408:
        return '请求超时';
      case 409:
        return '请求冲突';
      case 422:
        return '请求参数验证失败';
      case 429:
        return '请求过于频繁，请稍后重试';
      case 500:
        return '服务器内部错误';
      case 502:
        return '网关错误';
      case 503:
        return '服务不可用';
      case 504:
        return '网关超时';
      default:
        return '服务器错误 ($statusCode)';
    }
  }

  /// 根据状态码获取错误类型
  static NetworkErrorType _getErrorTypeFromStatusCode(int statusCode) {
    if (statusCode >= 400 && statusCode < 500) {
      if (statusCode == 401 || statusCode == 403) {
        return NetworkErrorType.authorization;
      }
      return NetworkErrorType.client;
    } else if (statusCode >= 500) {
      return NetworkErrorType.server;
    }
    return NetworkErrorType.unknown;
  }

  /// 是否为可重试的错误
  bool get isRetryable {
    switch (type) {
      case NetworkErrorType.timeout:
      case NetworkErrorType.network:
      case NetworkErrorType.server:
        return true;
      case NetworkErrorType.authorization:
      case NetworkErrorType.client:
      case NetworkErrorType.cancelled:
      case NetworkErrorType.parse:
      case NetworkErrorType.unknown:
        return false;
    }
  }

  /// 是否为认证相关错误
  bool get isAuthError => type == NetworkErrorType.authorization;

  /// 是否为客户端错误
  bool get isClientError => type == NetworkErrorType.client;

  /// 是否为服务器错误
  bool get isServerError => type == NetworkErrorType.server;

  /// 是否为网络连接错误
  bool get isNetworkError => type == NetworkErrorType.network;

  /// 是否为超时错误
  bool get isTimeoutError => type == NetworkErrorType.timeout;

  /// 获取详细的错误信息（用于调试）
  String get detailMessage {
    final buffer = StringBuffer();
    buffer.writeln('NetworkExceptionModel:');
    buffer.writeln('  Code: $code');
    buffer.writeln('  Message: $message');
    buffer.writeln('  Type: $type');
    
    if (statusCode != null) {
      buffer.writeln('  HTTP Status Code: $statusCode');
    }
    
    if (businessCode != null) {
      buffer.writeln('  Business Code: $businessCode');
    }
    
    if (requestMethod != null && requestPath != null) {
      buffer.writeln('  Request: $requestMethod $requestPath');
    }
    
    if (originalException != null) {
      buffer.writeln('  Original: $originalException');
    }
    
    return buffer.toString();
  }

  @override
  String toString() {
    return 'NetworkExceptionModel($code): $message';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is NetworkExceptionModel &&
        other.code == code &&
        other.message == message &&
        other.statusCode == statusCode &&
        other.businessCode == businessCode &&
        other.type == type;
  }

  @override
  int get hashCode {
    return code.hashCode ^
        message.hashCode ^
        statusCode.hashCode ^
        businessCode.hashCode ^
        type.hashCode;
  }
}

/// 网络错误类型枚举
enum NetworkErrorType {
  /// 网络连接错误
  network,
  
  /// 超时错误
  timeout,
  
  /// 认证/授权错误
  authorization,
  
  /// 客户端错误 (4xx)
  client,
  
  /// 服务器错误 (5xx)
  server,
  
  /// 请求取消
  cancelled,
  
  /// 数据解析错误
  parse,
  
  /// 未知错误
  unknown,
}

/// 网络错误类型扩展
extension NetworkErrorTypeExtension on NetworkErrorType {
  /// 获取错误类型的友好名称
  String get displayName {
    switch (this) {
      case NetworkErrorType.network:
        return '网络错误';
      case NetworkErrorType.timeout:
        return '超时错误';
      case NetworkErrorType.authorization:
        return '权限错误';
      case NetworkErrorType.client:
        return '请求错误';
      case NetworkErrorType.server:
        return '服务器错误';
      case NetworkErrorType.cancelled:
        return '请求取消';
      case NetworkErrorType.parse:
        return '数据错误';
      case NetworkErrorType.unknown:
        return '未知错误';
    }
  }

  /// 获取错误类型的图标
  String get icon {
    switch (this) {
      case NetworkErrorType.network:
        return '📶';
      case NetworkErrorType.timeout:
        return '⏱️';
      case NetworkErrorType.authorization:
        return '🔒';
      case NetworkErrorType.client:
        return '❓';
      case NetworkErrorType.server:
        return '🔧';
      case NetworkErrorType.cancelled:
        return '❌';
      case NetworkErrorType.parse:
        return '📄';
      case NetworkErrorType.unknown:
        return '⚠️';
    }
  }
}
